package miroshnichenko.gallery.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.QueryTimeoutException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class ExceptionHandlerController extends ResponseEntityExceptionHandler {

    private Logger log = LoggerFactory.getLogger(RegisterController.class);

    @ExceptionHandler(value = { DataAccessResourceFailureException.class })
    protected ResponseEntity<Object> handleDataAccessResourceFailure(DataAccessResourceFailureException ex, WebRequest request) {
        log.error("Database connection problems.", ex);

        String bodyOfResponse = "Database connection problems.";
        HttpStatus httpStatus = HttpStatus.SERVICE_UNAVAILABLE;

        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), httpStatus, request);
    }

    @ExceptionHandler(value = { DataAccessException.class })
    protected ResponseEntity<Object> handleDataAccess(DataAccessException ex, WebRequest request) {
        log.error("Database access problems.", ex);

        String bodyOfResponse = "Database access problems.";
        HttpStatus httpStatus = HttpStatus.SERVICE_UNAVAILABLE;

        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), httpStatus, request);
    }

    @ExceptionHandler(value = { MaxUploadSizeExceededException.class })
    protected ResponseEntity<Object> handledMaxUploadExceeded(MaxUploadSizeExceededException ex, WebRequest request) {
        log.error("Max upload file size exceeded.", ex);

        String bodyOfResponse = "Max upload file size exceeded.";
        HttpStatus httpStatus = HttpStatus.BAD_REQUEST;

        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), httpStatus, request);
    }

    @ExceptionHandler(value = { Exception.class })
    protected ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
        log.error("Exception handled by #handleAllExceptions", ex);

        String bodyOfResponse = "Something goes wrong.";
        HttpStatus httpStatus = HttpStatus.SERVICE_UNAVAILABLE;

        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), httpStatus, request);
    }


//    @ExceptionHandler(value = {DataAccessResourceFailureException.class})
//    @ResponseStatus(value = HttpStatus.SERVICE_UNAVAILABLE, reason = "Database connection failure!")
//    public ModelAndView handleDataAccessResourceFailure(DataAccessResourceFailureException darfe) {
//        log.error("Handling DataAccessResourceFailureException - Catching: " + darfe.getClass().getSimpleName(), darfe);
//        return errorModelAndView(darfe);
//    }
//
//    @ExceptionHandler(value = {DataAccessException.class})
//    @ResponseStatus(value = HttpStatus.SERVICE_UNAVAILABLE, reason = "Database access failure!")
//    public ModelAndView handleDataAccess(DataAccessException dae) {
//        log.error("Handling DataAccessResourceFailureException - Catching: " + dae.getClass().getSimpleName(), dae);
//        return errorModelAndView(dae);
//    }

//    private ModelAndView errorModelAndView(Exception e) {
//        ModelAndView modelAndView = new ModelAndView();
//        modelAndView.setViewName("error");
//        modelAndView.addObject("name", e.getClass().getSimpleName());
//
//        return modelAndView;
//    }
}
